package com.ydj.framework.third.cos;

import cn.hutool.http.HttpUtil;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.region.Region;
import com.ydj.AppEnvironment;
import com.ydj.framework.third.oss.res.TransferToOssByUrlDto;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;

@Slf4j
@Component
public class CosManager {
    @Value("${tencent.cos.secretId}")
    private String secretId;
    @Value("${tencent.cos.secretKey}")
    private String secretKey;
    @Value("${tencent.cos.region}")
    private String region;


    @Value("${tencent.cos.bucketName}")
    private String bucketName;
    @Getter
    @Value("${tencent.cos.baseUrl}")
    private String baseUrl;


    @Autowired
    private AppEnvironment appEnvironment;

    /**
     *
     * @param objectName OSS里的路径，不包含Bucket名。例如 exampledir/exampleobject.txt
     */
    public String uploadFile(byte[] content, String objectName) {
        COSClient cosClient = createCosClient();
        try {
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(content.length);

            // 4. 指定要上传的文件的路径和名称。
            // 创建上传对象的请求。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new ByteArrayInputStream(content), metadata);

            // 5. 执行上传操作。
            PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);

            return baseUrl + objectName;
        } finally {
            // 6. 关闭客户端。
            cosClient.shutdown();
        }
    }

//    /**
//     *
//     * @param objectName OSS里的路径，不包含Bucket名。例如 exampledir/exampleobject.txt
//     */
//    public boolean uploadByUrl(String srcUrl, String objectName) {
//        // 创建OSSClient实例。
//        COSClient cosClient = createCosClient();
//        InputStream inputStream = null;
//        try {
//            URL url = new URL(srcUrl);
//            inputStream = url.openStream();
//
//            ObjectMetadata metadata = new ObjectMetadata();
//            metadata.setContentLength(content.length);
//
//            // 创建PutObjectRequest对象。
//            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);
//
//            // 如果需要上传时设置存储类型和访问权限，请参考以下示例代码。
////             ObjectMetadata metadata = new ObjectMetadata();
////             metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
////             metadata.setObjectAcl(CannedAccessControlList.PublicRead);
////             putObjectRequest.setMetadata(metadata);
//
//            // 设置该属性可以返回response。如果不设置，则返回的response为空。
//            putObjectRequest.setProcess("true");
//            // 上传字符串。
//            PutObjectResult result = ossClient.putObject(putObjectRequest);
//            // 如果上传成功，则返回200。
//            if (result.getResponse().getStatusCode() != 200) {
//                log.error("通过URL上传OSS图片错误。status code={}, srcUrl={}, objectName={}", result.getResponse().getStatusCode(), srcUrl, objectName);
//                CommonException.throwException("通过URL上传OSS图片失败, status code=" + result.getResponse().getStatusCode());
//            } else {
//                log.info("通过URL上传OSS图片成功。srcUrl={}, objectName={}", srcUrl, objectName);
//                return true;
//            }
//        } catch (Exception oe) {
//            log.error("通过URL上传OSS图片失败", oe);
//        } finally {
//            CloseUtil.close(inputStream);
//            if (ossClient != null) {
//                ossClient.shutdown();
//            }
//        }
//        return false;
//    }

    public void delete(String url) throws Exception {
        if (StringUtils.isBlank(url)) {
            return;
        }
        String objectName = url;
        if (objectName.startsWith(baseUrl)) {
            objectName = objectName.substring(baseUrl.length());
        }

        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);

        // 创建OSSClient实例。
        Region region = new Region("ap-guangzhou");
        ClientConfig clientConfig = new ClientConfig(region);
        COSClient cosClient = new COSClient(cred, clientConfig);
        try {
            // 删除文件或目录。如果要删除目录，目录必须为空。
            cosClient.deleteObject(bucketName, objectName);
        } catch (Exception oe) {
            log.error("通过删除OSS文件失败，objName=" + objectName, oe);
        } finally {
            cosClient.shutdown();
        }
    }

    /**
     * 通过 URL 转存文件到 OSS
     *
     * @param url           源URL
     * @param cosFullPath   COS 全路径
     */
    public TransferToOssByUrlDto transferToOssByUrl(String url, String cosFullPath) {
        TransferToOssByUrlDto dto = new TransferToOssByUrlDto();

        byte[] downloadData = null;
        try {
            downloadData = HttpUtil.downloadBytes(url);
        } catch (Exception ignored) {
        }
        if (downloadData == null) {
            dto.setResult(TransferToOssByUrlDto.TransferToOssResult.下载文件失败);
            return dto;
        }

        String uploadUrl = uploadFile(downloadData, cosFullPath);
        if (uploadUrl == null) {
            dto.setResult(TransferToOssByUrlDto.TransferToOssResult.上传失败);
        } else {
            dto.setResult(TransferToOssByUrlDto.TransferToOssResult.上传成功)
                    .setOssUrl(uploadUrl);
        }
        return dto;
    }

    private COSClient createCosClient() {
        // 1. 初始化用户身份信息（secretId, secretKey）。
        // 您可以直接在代码中硬编码这些值，也可以从安全的源中读取。
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);

        // 2. 设置 bucket 的地域, COS地域的编码规则请参照 https://cloud.tencent.com/document/product/436/6224
        Region regionObj = new Region(region);

        // 3. 生成 cos 客户端。
        ClientConfig clientConfig = new ClientConfig(regionObj);
        COSClient cosClient = new COSClient(cred, clientConfig);

        return cosClient;
    }
}
